﻿using Delphi.Apoll.Util;
using Delphi.Isis.Yahoo;
using Delphi.Janus.Util;
using Delphi.Mimir.Data.Bulk;
using Delphi.Mimir.Data.Entities.Final;
using Delphi.Mimir.Data.Entities.Final.Helpers;
using Delphi.Mimir.Data.Entities.Raw;
using Delphi.Mimir.Data.Procedures;
using Delphi.Mimir.Wrapper;
using Quartz;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace Delphi.Apoll.Updater {
    class YahooUpdater : IJob, IDisposable, IUpdater {
        public void Dispose() {
            return;
        }

        public void Execute(IJobExecutionContext context) {
            throw new NotImplementedException();
        }

        public void UpdateAll() {
            ICollection<ExchangeLastLoad> ell = ExchangeWrapper.GetLastLoads();

            foreach (ExchangeLastLoad el in ell) {
                ICollection<ExchangeLastLoad.LastLoadControls> llc = el.LastControls.ToList();
                foreach (ExchangeLastLoad.LastLoadControls lc in llc) {
                    DateTime lastLoadedTradeDate = new DateTime();
                    // DateTime when the next trade date should be loaded --> lastLoaderdTradeDate + 1 Bus Day + Offsets
                    DateTime nextLoadDue = new DateTime();
                    // whenever a temp date comes in handy.....
                    DateTime tempDate = new DateTime();

                    // Handle null date
                    if (lc.LastLoad == null) {
                        lastLoadedTradeDate = DateTime.UtcNow.NextBusinessDays(-3);
                    } else {
                        lastLoadedTradeDate = lc.LastLoad.TradeDate;
                    }




                }
            }
        }

        public void LoadFullHistory() {
            ICollection<Exchange> excs = ExchangeWrapper.GetExchanges();
            foreach(Exchange e in excs) {
                LoadFullHistory(e);
            }
        }

        public void LoadFullHistory(string exchangeCode) {
            Exchange e = ExchangeWrapper.GetExchange(exchangeCode);
            LoadFullHistory(e);
        }

        public void LoadFullHistory(Symbol symbol) {
            // earliest trade date in database
            DateTime startDate = SymbolWrapper.GetEarliestTradeDate(symbol);
            List<string[]> quotes = YahooApi.GetQuoteHistorty(symbol.YahooCode, new DateTime(1950, 1, 1));
            if (quotes != null && quotes.Count > 0) {
                // check last (-> earliest) quote
                DateTime yahooStartDate = DateTime.ParseExact(quotes.Last()[0].Trim(), "yyyy-MM-dd", CultureInfo.InvariantCulture);
                // only update database if db has shorter history
                if (startDate.AddDays(7) >= yahooStartDate) {
                    // let's do this!
                    List<RawQuote> rawQuotes = new List<RawQuote>();
                    foreach (string[] str in quotes) {
                        RawQuote q = new RawQuote();
                        q.qot_sym_cd = symbol.Code;
                        q.qot_exc_cd = symbol.Exchange.Code;
                        q.qot_period = "D";
                        q.qot_trade_dt = DateTime.ParseExact(str[0].Trim(), "yyyy-MM-dd", CultureInfo.InvariantCulture);
                        q.qot_open = Decimal.Parse(str[1].Trim());
                        q.qot_high = Decimal.Parse(str[2].Trim());
                        q.qot_low = Decimal.Parse(str[3].Trim());
                        q.qot_close = Decimal.Parse(str[4].Trim());
                        q.qot_volume = Int64.Parse(str[5].Trim());
                        if (Decimal.Parse(str[4].Trim()) != 0) {
                            q.qot_adj_factor = Decimal.Parse(str[6].Trim()) / Decimal.Parse(str[4].Trim());
                        }
                        rawQuotes.Add(q);
                    }
                    // Clear Table
                    Etl.ClearTable("raw.eod_quotes");
                    // Get the data into the tables
                    BulkLoad bl = BulkLoad.GetInstance();
                    bl.Persist(rawQuotes.ToArray());
                    Etl.EodQuotesApi();
                    // and clear the table again
                    Etl.ClearTable("raw.eod_quotes");
                    Console.WriteLine(string.Format("{0} Quotes Done!", rawQuotes.Count()));
                } else {
                    Console.WriteLine("Nothing to do!");
                }
                // Bug Fix Id 4
                symbol.IsYahooProcessed = true;
                symbol.IsYahoo = true;
                symbol.GoogleCode = null;
                SymbolWrapper.UpdateSymbol(symbol);
            } else {
                // --> no history whatsoever so unset yahoo flag
                symbol.IsYahoo = false;
                symbol.GoogleCode = null;
                SymbolWrapper.UpdateSymbol(symbol);
                Console.WriteLine("Removed as Yahoo Symbol!");
            }
        }


        public void LoadFullHistory(Exchange exchange) {
            ICollection<Symbol> symbols = SymbolWrapper.GetYahooSymbols(exchange, true);
            int count = symbols.Count;
            foreach (Symbol sym in symbols) {
                Console.Write(string.Format("Loading {0}:{1}... ({2} to go) ", sym.Code, sym.Exchange.Code, count));
                --count;
                LoadFullHistory(sym);
            }
        }

        public void LoadFullHistoryNewSymbols() {
            ICollection<Symbol> symbols = SymbolWrapper.GetNewYahooSymbols();
            int count = symbols.Count;
            foreach (Symbol sym in symbols) {
                Console.Write(string.Format("Loading {0}:{1}... ({2} to go) ", sym.Code, sym.Exchange.Code, count));
                --count;
                LoadFullHistory(sym);
            }
        }

        public int? UpdateCorporateAction(string exchangeCode, DateTime startDate) {
            return UpdateCorporateAction(ExchangeWrapper.GetExchange(exchangeCode), startDate);
        }

        public int? UpdateCoporateActionNewSymbol() {
            ICollection<Symbol> symbols = SymbolWrapper.GetYahooSymbols(true);

            try {
                foreach (Symbol sym in symbols) {
                    List<RawCorporateAction> corporateActions = new List<RawCorporateAction>();
                    // start 7 days earlier, as not sure when ca are updated
                    List<string[]> actions = YahooApi.GetCorporateAction(sym.YahooCode, new DateTime(1960, 1, 1));
                    //List<string[]> actions = YahooApi.GetCorporateAction(sym.Code, new DateTime(1960, 1, 1));
                    Console.WriteLine("     " + sym.Code);
                    if (actions != null && actions.Count > 0) {
                        foreach (string[] str in actions) {
                            RawCorporateAction ca = new RawCorporateAction();
                            ca.coa_sym_cd = sym.Code;
                            ca.coa_exc_cd = sym.Exchange.Code;
                            ca.coa_action_desc = str[0].Substring(0, 1).ToUpper() + str[0].Substring(1).ToLower();
                            ca.coa_action_dt = DateTime.ParseExact(str[1].Trim(), "yyyyMMdd", CultureInfo.InvariantCulture);
                            //ca.coa_amount
                            if (str[2].IndexOf(':') > 0) {
                                string[] splits = str[2].Split(':');
                                ca.coa_amount = Decimal.Parse(splits[0].Trim()) / Decimal.Parse(splits[1].Trim());
                            } else {
                                ca.coa_amount = Decimal.Parse(str[2].Trim());
                            }
                            corporateActions.Add(ca);
                        }
                    }
                    CorporateActionWrapper.SetCorporateActions(corporateActions);
                }
            } catch (Exception e) {
                Log.Write("YahooUpdater.UpdateCorporateAction()", e);
                Log.Write(e.StackTrace);
                return null;
            }
            return 1;
        }


        public int? UpdateCorporateAction(Exchange exchange, DateTime startDate) {
            ICollection<Symbol> symbols = SymbolWrapper.GetYahooSymbols(exchange, true);
            int counter = 0;

            try {
                foreach (Symbol sym in symbols) {
                    List<RawCorporateAction> corporateActions = new List<RawCorporateAction>();
                    // start 7 days earlier, as not sure when ca are updated
                    List<string[]> actions = YahooApi.GetCorporateAction(sym.YahooCode, startDate);
                    //List<string[]> actions = YahooApi.GetCorporateAction(sym.Code, new DateTime(1960, 1, 1));
                    Console.WriteLine("     " + sym.Code);
                    if (actions != null && actions.Count > 0) {
                        foreach (string[] str in actions) {
                            RawCorporateAction ca = new RawCorporateAction();
                            ca.coa_sym_cd = sym.Code;
                            ca.coa_exc_cd = sym.Exchange.Code;
                            ca.coa_action_desc = str[0].Substring(0, 1).ToUpper() + str[0].Substring(1).ToLower();
                            ca.coa_action_dt = DateTime.ParseExact(str[1].Trim(), "yyyyMMdd", CultureInfo.InvariantCulture);
                            //ca.coa_amount
                            if (str[2].IndexOf(':') > 0) {
                                string[] splits = str[2].Split(':');
                                ca.coa_amount = Decimal.Parse(splits[0].Trim()) / Decimal.Parse(splits[1].Trim());
                            } else {
                                ca.coa_amount = Decimal.Parse(str[2].Trim());
                            }
                            corporateActions.Add(ca);
                        }
                    }
                    counter += corporateActions.Count;
                    CorporateActionWrapper.SetCorporateActions(corporateActions);
                }
            } catch (Exception e) {
                Log.Write("YahooUpdater.UpdateCorporateAction()", e);
                Log.Write(e.StackTrace);
                return null;
            }

            /*
            if (corporateActions.Count > 0) {
                //Etl.ClearTable("raw.eod_corporate_actions");
                CorporateActionWrapper.SetCorporateActions(corporateActions);
                //Etl.EodCorporateActionsApi();
                //Etl.ClearTable("raw.eod_corporate_actions");
            }*/
            return counter;
        }
    }
}

